// File:   LCDCOMMANDS.asm
// Created:  Feb 28, 2009
// Creator:  Marcin Misiewicz
//
// DESCRIPTION:
//   Controls the SGD-A LCD from Sparkfun Electronics
//    6lines x 14 characters/line = 84 Characters
//
// Commands Available:
// **********************************************************************************************************
//�B� Bitmap - (B b1 b2 b3 b4 b5 b6... bn) Sends  to display the bitmap that is  being received in Rx pin
//�C� Contrast -(C n)Adjusts LCD contrast. SGD-A is temperature compensated, so this command normally is unnecessary
//�D� Read-Ram Reads a byte of user RAM , that is  64 bytes.
//�E� Write-Ram Writes a byte of user RAM, that is  64 bytes.
//�L� Line Draws a line. It starts from last coordinates of pointer (Look at command �P�) and ends in selected coordinates.
//�N� CLS  Clears screen  and places the pointer at (0,0) (top left corner)
//�P� Locate Places the pointer in the selected coordinates. It is suitable to place text or lines.
//�R� Read-eeprom Read a byte of user EEPROM, that is 128 bytes.
//�W� Write-eeprom Writes a byte of user EEPROM, that is 128 bytes.
//�S� String Writes a string of text in current coordinates.
//�T� Tone Outputs a tone of frequency and time selected.
//        T,p,e,t 
//		p=0-255 (timer count), e=prescaler of timer=1-16, t=toneduration=0-255
//   duration = 8.1*t (ms)
//  freq = 1 / ( 2*(p+1)*e*10^-6) Hz
//  T,12,249,2 1khz for 97ms
//�F� Firmware Revision  Displays a  FW version of SGD-A.
//�X� Ping Outputs a �X� in Tx. Useful to debug a connection and operation of display.
//�Z�  Sleep  Start low power mode. should ping and wait for proper reply to get
//***********************************************************************************************************
//#define  bitmap   0
//#define  contrast   1
//#define  readram     2
//#define  writeram  3
//#define line   4
//#define  clearscr  5
//#define  movep   6
//#define  readeeprom  7
//#define  writeeeprom  8
//#define  string    9
//#define  tone   10
//#define   firmware  11
//#define  ping   12
//#define  sleep   13





//=====ARGUMENTS========
//For Single argument commands, ARG0 -> R0
//For double argument commands, ARG0 -> R0, ARG1 -> R1
//
//=====RETURN VALUES====
//For functions returning a value
//For Bitmap

//////////////////////////////////////////////////////////////////////
//function: Drawmenu
//description: will send output to GPC0 using putuart of the string stored at memory location given by R1.
//      String must be nullterminated. Will output a max of 14*6=84 + 6 Carriage return = 90 max characters as a last ditch stop runaway

//    This function clears everything on the screen
//input arguments: R0-> memory location of start of string
//output arguments: none
//written by: marcin
//example:        mov r0, ViewStatus2 //loads memory location of menu to r0
 //		       jsr r6, DrawMenu  
 //This will draw the screen specified by the array of strings at memory location StringMemLoc and terminated by EOS. (Lines must be seperated by CR)
//**IMPORTANT!!!!: IF your text gets to the end of the row (xx=14) an AUTOMATIC carriage return happens
//****************CHANGELOG**********************88
//march18-edit1: 15:32 - fixed St Ld error, and double checked code. Counts should work and no fencposting errors should occur


	
DrawMenu:
  st r0, sp, 0 //MemoryLocation for start of string
  st r1, sp, 1 //output register for PutUART,
  st r2, sp, 2
  st r3, sp, 3 //scratch
  st r4, sp, 4
  st r5, sp, 5 //scratch
  st r6, sp, 6 //scratch
  add sp, sp, 7

  mov r2, 0x0000   //counter to see how many characters before null
  mov r4, 0x0000  //scratch

  ld r3, r0,0  // loads rs with first byte
  bc ZS, foundEOS  //found EOS (0x00), branching to end)

//lookingforEOS:     //find first occurance of 0x0000 *EOS* from our start memory
//  add r2, r2, 1  //didnt find EOS, increment //r2 is counter
 // st r2, offsetCount  //stores value of r2 into mem offsetcount to use in addressing workaround
 // ld r3, r0, offsetCount  //loads ( r0+offsetcount (r2) )  into r3
//  bc  ZS, foundEOS  //found EOS 0x0000, branch to foundEOS
  
  
lookingforEOS:     //find first occurance of 0x0000 *EOS* from our start memory
  add	r0,r0,1
  add r2, r2, 1  //didnt find EOS, increment //r2 is counter
  ld r3, r0, 0  //loads ( r0+offsetcount (r2) )  into r3
  bc  ZS, foundEOS  //found EOS 0x0000, branch to foundEOS
  

    
  
  add r4, r2, -90   //counter > 90?
  bc ZS, stringOverflow   //string longer than 90 characters, bra to overflow /
  bra lookingforEOS   //didnt find EOS and <90 char length, loop and try again

stringOverflow:        //string was longer than 90 characters, r2 length set to 90 and string outputted, you may have problems if this is hit
  mov r2, 90

foundEOS:     //r2 now has length of string that will be passed to the LCD, no fencepost error because r2count doesnt include EOS.
  ld	r0,sp,-7  //restore string pointer
  
  mov r1, 'N'  //Clears screen
  jsr r6, putUART  //clears screen

 jsr r6, DelayReallyLong //waits for screen to be cleared


  mov r1, 'S'   //send 'string of length n' command to lcd
  jsr r6, putUART

  mov r1, r2
  jsr r6, putUART   //sends #ofcharsinstring


 
  
  //R2 has the number of bytes in our string now.
  //r0 has start location of string
  //r5 is counter
  mov r5, 0x0000  //clears counter
  mov r4, 0x0000  // reset temp counter

drawmenuLoop:

  ld  r3, r0, 0  //r3 = (r0) character we want to send
  bc ZS, finishedDraw  //check if it is a EOS, and branch to end if so //this is a mistake, needs to finish outputting that EOS string //or does it


  mov r1, r3   //makes copy of character to send
  jsr r6, putUART  //valid character, transmit first byte

  add r0, r0, 1 //increments read mem loc
  add r5, r5, 1 //increments counter
  

  sub r4, r5, r2     // r5= counter, r2 = actual. want to branch if r5>r2, meaning next count is above the length of string
  bc GT, finishedDraw  // all  characters written on the screen, branch to end 
    
  bra drawmenuLoop  //all characters not finished keep looping

  finishedDraw:
  //finished outputting, clean up the registers
  sub sp, sp, 7
  ld r0, sp, 0
  ld r1, sp, 1
  ld r2, sp, 2
  ld  r3, sp, 3
  ld   r4, sp, 4
  ld r5, sp, 5
  ld  r6, sp, 6
  jsr r6, r6






//////////////////////////////////////////////////////////////////////
//function: MovePointerPixel
//description: Moves pointer to pixel location X,Y on the screen
//input arguments: R0-> 0x XX YY (xx and yy is in hex)
//  NOTE: Limit for XX = 83 = 0x53 CODE DOESNT CHECK FOR OVERFLOW
//  NOTE: Limit for YY = 47 = 0x2F CODE DOESNT CHECK FOR OVERFLOW
//output arguments: none
//
//written by: marcin
//example:  mov r0, 0x#### (xx yy must be converted to hex 0x####)
//   jsr r6, MovePointerPixel //moves pointer to PIXEL location XX, YY on screen
///////////////////////////////////////////////////////////////////////
MovePointerPixel:

  st r0, sp, 0 //input paramter - desired pixel location
  st r1, sp, 1 //output register for putUART,
  st r2, sp, 2 //scratch
  st   r6, sp, 3 //jsr protect
  add sp, sp, 4


  mov r2, r0
  rol r2, r2, -8 //gets xx value in lsbyte of r2
  mov r1, 'P'
  jsr r6, putUART //outputs P signalling for pointer
  mov r1, r2
  jsr r6, putUART //outputs XX
  mov r1, r0
  jsr r6, putUART //outputs YY


  sub sp, sp, 4
  ld r0, sp, 0
  ld r1, sp, 1
  ld r2, sp, 2
  ld  r6, sp, 3
  jsr r6, r6
//////////////////////////////////////////////////////////////////


///UpdateCursor////
//input: r1  =  old cursor location in HEX ( Y =  (never0) , 8,  16,  24, 32, 40 
//						         HEXVALUES,    ,x8  x10  x18 x20, 28
//	   r2  =  new cursor location ( y =  (never0) , 8, 16, 24, 32, 40
//		//will never be y=0 top, always reserved for menu
//output: None
//Doesn't butcher old or new cursor location values
UpdateCursor:
	st 	r0, sp, 0 //scratch
	st 	r1, sp, 1 //firstvar
	st 	r2, sp, 2 //secondvar
	st	r6, sp, 3 //stack pointer
	add 	sp, sp, 4
	
	mov	r0, r1
	jsr	r6, MovePointerPixel 	//moves pointer to old cursor location
	mov	r1, 'S'
	jsr	r6, putUART
	mov	r1, 1
	jsr	r6, putUART
	mov	r1, ' '
	jsr	r6, putUART 		//clears old pointer location with blank
	
	mov	r0, r2			//moves pointer to new cursor location	
	jsr	r6, MovePointerPixel
	mov	r1, 'S'
	jsr 	r6, putUART
	mov	r1, 1
	jsr	r6, putUART
	mov	r1, '>'
	jsr	r6, putUART			//moves cursor to new location
	
	
	sub 	sp, sp, 4
	ld	r0, sp, 0
	ld	r1, sp, 1
	ld	r2, sp, 2
	ld	r6, sp, 3
	
	//////////////////////////////////////////////////////////////////////